/*
 * CAM.h
 *
 *  Created on: 2023閿熸枻鎷�1閿熸枻鎷�18閿熸枻鎷�
 *      Author: 0
 */

#ifndef CODE_CAM_H_
#define CODE_CAM_H_
#include "zf_common_headfile.h"

// 图像结构体
typedef struct image {
    uint8 *data;    // 图像
    uint32 width;   // 图像宽度,x
    uint32 height;  // 图像长度,y
    uint32 step;    // 一行的长度,用于计算在图像数组中的下标
} image_t;

// 图像,横x竖y
#define AT_IMAGE(img, x, y)          ((img)->data[(y)*(img)->step + (x)])
// 默认对图像结构体初始化
#define DEF_IMAGE(ptr, w, h)         {.data=ptr, .width=w-1, .height=h, .step=w}
// 边线数组长度
#define POINTS_MAX_LEN (120)// (MT9V03X_H)
// 远边线数组长度
#define FAR_POINTS_MAX_LEN  (POINTS_MAX_LEN)

// AT_IMAGE缩写
#define AT AT_IMAGE
// AT_IMAGE限制范围查询
#define AT_CLIP(img, x, y)  AT_IMAGE((img), clip((x), 0, (img)->width-1), clip((y), 0, (img)->height-1));
// 赛道宽度
#define ROAD_WIDTH      (0.45)

extern image_t img_raw;

// 循线标志选择
enum track_type_e {
    TRACK_LEFT,         // 循左线
    TRACK_RIGHT,        // 循右线
    TRACK_CROSS_LEFT,   // 循十字左线
    TRACK_CROSS_RIGHT,  // 循十字右线
    TRACK_CIRCLE_LEFT,  // 循圆环左线
    TRACK_CIRCLE_RIGHT, // 循圆环右线
    TRACK_GARAGE_LEFT,  // 循车库左线
    TRACK_GARAGE_RIGHT, // 循车库右线
    TRACK_NUM           // 循线状态数量
};

extern const char *track_type_name[TRACK_NUM];

extern float thres;
extern float block_size;
extern float clip_value;

extern float begin_x;
extern float begin_y;

extern float line_blur_kernel;

extern float pixel_per_meter;

extern float sample_dist;
extern float angle_dist;    //0.2

extern int aim_idx;

extern float aim_distance;

extern bool adc_cross ;

extern int ipts0[POINTS_MAX_LEN][2];
extern int ipts1[POINTS_MAX_LEN][2];
extern int ipts0_num,ipts1_num;

extern float rpts0[POINTS_MAX_LEN][2];
extern float rpts1[POINTS_MAX_LEN][2];
extern int rpts0_num, rpts1_num;

extern float rpts0b[POINTS_MAX_LEN][2];
extern float rpts1b[POINTS_MAX_LEN][2];
extern int rpts0b_num, rpts1b_num;

extern float rpts0s[POINTS_MAX_LEN][2];
extern float rpts1s[POINTS_MAX_LEN][2];
extern int rpts0s_num, rpts1s_num;

extern float rpts0a[POINTS_MAX_LEN];
extern float rpts1a[POINTS_MAX_LEN];
extern int rpts0a_num, rpts1a_num;

extern float rpts0an[POINTS_MAX_LEN];
extern float rpts1an[POINTS_MAX_LEN];
extern int rpts0an_num, rpts1an_num;

extern float rptsc0[POINTS_MAX_LEN][2];
extern float rptsc1[POINTS_MAX_LEN][2];
extern int rptsc0_num, rptsc1_num;


extern float (*rpts)[2];
extern int rpts_num;

extern float rptsn[POINTS_MAX_LEN][2];
extern int rptsn_num;
extern int real_aim;


extern int Lpt0_rpts0s_id_left, Lpt0_rpts0s_id_right,Lpt1_rpts1s_id_left, Lpt1_rpts1s_id_right;
extern bool Lpt0_found_left,Lpt0_found_right, Lpt1_found_left,Lpt1_found_right;

extern bool is_straight0, is_straight1;
extern bool is_bend0, is_bend1;

extern float error;

extern bool is_turn0, is_turn1;

extern enum track_type_e track_type;
extern bool is_straight0, is_straight1;

void process_image (void);
void findline_lefthand_adaptive (image_t *img, int half, int clip_value, int x, int y, int pts[][2], int *num,int step_num);
void findline_righthand_adaptive (image_t *img, int half, int clip_value, int x, int y, int pts[][2], int *num,int step_num);
void blur_points(float pts_in[][2], int num, float pts_out[][2], int kernel);
void resample_points(float pts_in[][2], int num1, float pts_out[][2], int *num2, float dist);
void resample_points2(float pts_in[][2], int num1, float pts_out[][2], int *num2, float dist);
void local_angle_points(float pts_in[][2], int num, float angle_out[], int dist);
void nms_angle(float angle_in[], int num, float angle_out[], int kernel);
void track_leftline(float pts_in[][2], int num, float pts_out[][2], int approx_num, float dist);
void track_rightline(float pts_in[][2], int num, float pts_out[][2], int approx_num, float dist);
//void find_corners (void);
void find_corners_polarity (void);
void check_bend(void);
uint16 GetOSTU (uint8 tmImage[][MT9V03X_W]);
uint16 dim_GetOSTU (uint8 tmImage[][MT9V03X_W]);

int clip(int x, int low, int up);
float fclip(float x, float low, float up);

void cam(void);

#endif /* CODE_CAM_H_ */
